package com.powernode.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.domain.Basket;
import com.powernode.domain.Prod;
import com.powernode.domain.Sku;
import com.powernode.exception.CartException;
import com.powernode.feign.CartProdFeign;
import com.powernode.service.BasketService;
import com.powernode.mapper.BasketMapper;
import com.powernode.vo.CartItem;
import com.powernode.vo.CartMoney;
import com.powernode.vo.CartVo;
import com.powernode.vo.ShopCart;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class BasketServiceImpl extends ServiceImpl<BasketMapper, Basket>
        implements BasketService {

    @Autowired
    private BasketMapper basketMapper;

    @Autowired
    private CartProdFeign cartProdFeign;


    @Override
    public CartVo basketInfo(String wxUserId) {
        CartVo cartVo = new CartVo();
        List<ShopCart> shopCartList = new ArrayList<>();
        //根据用户id查询到该用户所加的索引商品
        List<Basket> basketList = basketMapper.selectList(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getUserId, wxUserId));
        //判断该用户加过购物车没
        if (CollectionUtil.isNotEmpty(basketList)) {

            //获取到所有的skuid 和prodid
            List<Long> skuIds = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
            List<Long> prodIds = basketList.stream().map(Basket::getProdId).collect(Collectors.toList());
            //根据prodids查询对应的商品 并将其以id和商品进行map
            List<Prod> prodList = cartProdFeign.loadProdById(prodIds);
            Map<Long, Prod> prodMap = prodList.stream().collect(Collectors.toMap(Prod::getProdId, prod -> prod));
            //根据skuids查询对应的sku 并将其以id和sku进行map
            List<Sku> skuList = cartProdFeign.loadSkuById(skuIds);
            Map<Long, Sku> skuMap = skuList.stream().collect(Collectors.toMap(Sku::getSkuId, sku -> sku));
            //以shopId对basketList进行分组
            Map<Long, List<Basket>> shopMap = basketList.stream().collect(Collectors.groupingBy(Basket::getShopId));
            shopMap.forEach((shopId, baskets) -> {
                ShopCart shopCart = new ShopCart();
                ArrayList<CartItem> cartItems = new ArrayList<>();
                baskets.forEach(basket -> {
                    //根据相应id获得sku和prod
                    Prod prod = prodMap.get(basket.getProdId());
                    Sku sku = skuMap.get(basket.getSkuId());
                    //将basket数据拷贝到cartItem中
                    CartItem cartItem = new CartItem();
                    BeanUtil.copyProperties(basket, cartItem);
                    //将sku和prod相应数据拷贝到cartItem
                    BeanUtil.copyProperties(prod, cartItem);
                    BeanUtil.copyProperties(sku, cartItem);
                    cartItems.add(cartItem);
                });
                //将商品信息添加到shopcart中
                shopCart.setShopCartItems(cartItems);
                shopCartList.add(shopCart);
            });
        }
        cartVo.setShopCarts(shopCartList);
        return cartVo;
    }

    /**
     * 将购物车容量定为50
     *
     * @param basket
     * @param wxUserId
     */
    @Override
    public void changeItem(Basket basket, String wxUserId) {
        //根据skuid userid prodid 查询出
        Basket old = basketMapper.selectOne(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getProdId, basket.getProdId())
                .eq(Basket::getSkuId, basket.getSkuId())
                .eq(Basket::getUserId, wxUserId)
        );
        if (ObjectUtils.isEmpty(old)) {
            //根据用户id进行判断
            Integer count = basketMapper.selectCount(new LambdaQueryWrapper<Basket>()
                    .eq(Basket::getUserId, wxUserId));
            /**
             * 对购物车进行查询
             * 如果存在添加的商品就修改数量即可
             */
            if (count >= 50) {
                //todo 在common定义全局异常
                throw new CartException("购物车容量已经达到最大，请先处理购物车数量");
            }
            //没超过就可以插入
            basket.setUserId(wxUserId);
            basket.setBasketDate(new Date());
            basketMapper.insert(basket);
        } else {
            //获取到数量  由于传过来的值是带符号的
            int count = old.getBasketCount() + basket.getBasketCount();
            if (count > 0) {
                //修改
                old.setBasketCount(count);
                basketMapper.updateById(old);
            } else {
                //删除
                basketMapper.deleteById(old);
            }
        }
    }

    /**
     * 计算商品价格
     *
     * @param basketIds
     * @return
     */
    @Override
    public CartMoney totalPay(List<Long> basketIds) {
        CartMoney cartMoney = new CartMoney();
        if (CollectionUtil.isNotEmpty(basketIds)) {
            //获取所有的商品
            List<Basket> baskets = basketMapper.selectBatchIds(basketIds);
            List<Long> skuId = baskets.stream().map(Basket::getSkuId).collect(Collectors.toList());
            List<Sku> skuList = cartProdFeign.loadSkuById(skuId);
            Map<Long, Sku> skuMap = skuList.stream().collect(Collectors.toMap(Sku::getSkuId, sku -> sku));
            //定义一个集合 用来保存所有sku对应的单品总价
            ArrayList<BigDecimal> totalList = new ArrayList<>();
            baskets.stream().forEach(basket -> {
                Sku sku = skuMap.get(basket.getSkuId());
                //获得某个商品的sku价格
                BigDecimal price = sku.getPrice();
                //获得加入到购物车的该sku总价 一个商品
                Integer count = basket.getBasketCount();
                BigDecimal oneTotalPrice = price.multiply(new BigDecimal(count));
                totalList.add(oneTotalPrice);
            });
            //使用list集合求和方法得到总价格
            BigDecimal totalMoney = totalList.stream().reduce(BigDecimal::add).get();

            //定义运费
            /*
             * 此处业务逻辑而定
             * 当总价格达到多少元则没有运费 如果没达到则添加多少元的运费
             * 50  8
             * */
            //运费定义为0
            BigDecimal transMoney = BigDecimal.ZERO;
            //优惠也为0
            BigDecimal subtractMoney = BigDecimal.ZERO;
            BigDecimal finalMoney = BigDecimal.ZERO;
            if (totalMoney.intValue() > 50) {
                //运费为0 优惠为运费8
                transMoney = new BigDecimal(0);
                subtractMoney = new BigDecimal(8);
                //总价格为商品总价格
                finalMoney=totalMoney;
            }else {
                //运费为8 优惠为0 总价格为商品价格+运费
                transMoney = new BigDecimal(8);
                subtractMoney = new BigDecimal(0);
                finalMoney=totalMoney.add(transMoney);
            }
            cartMoney.setFinalMoney(finalMoney);
            cartMoney.setSubtractMoney(subtractMoney);
            cartMoney.setTransMoney(transMoney);
            cartMoney.setTotalMoney(totalMoney);
        }


        return cartMoney;
    }
}




